<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\cdc\cost\pull;

use app\enum\CommonEnum;
use app\enum\QqEnum;
use app\enum\ServiceCostEnum;
use app\enum\TokenEnum;
use app\model\CostTaskAccountModel;
use app\service\BaseService;
use app\service\cdc\cost\TaskNoticeService;
use app\service\client\AccountService;
use app\service\qq\FinanceService;
use app\service\qq\MaterialService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

class QqService extends BaseService implements PullInterface
{
    private array $params = [];

    /**
     * @var bool|mixed|string
     */
    private array $response = [];

    private array $thisResponseData = [];

    /**
     * @var array 返回体
     */
    private array $responseData = [];

    /**
     * @return bool 请求数据是否为空
     */
    public function isResponseEmpty(): bool
    {
        return empty($this->thisResponseData);
    }

    /**
     * 获取返回码.
     * @return mixed
     */
    public function getResponseCode()
    {
        return $this->response['code'] ?? '-10000';
    }

    /**
     * 获取返回错误信息.
     * @return mixed
     */
    public function getResponseMsg()
    {
        return $this->response['message'] ?? '';
    }

    /**
     * 获取返回体.
     */
    public function getResponseData(array $args = []): array
    {
        return $this->responseData;
    }

    /**
     * 判断服务.
     */
    public function isResponseSuccess(): bool
    {
        return FinanceService::isResponseSuccess($this->getResponseCode());
    }

    /**
     * 获取请求头部.
     */
    public function getHeader(string $token = ''): array
    {
        return FinanceService::getHeader($token);
    }

    /**
     * 获取媒体.
     */
    public function getMediaId(): int
    {
        return CommonEnum::QQ_MEDIA;
    }

    /**
     * 获取账户流水.
     * @param CostTaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAdvertiserDailyFlow(CostTaskAccountModel $model): bool
    {
        // 32430969_QQ_TOKEN
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'), TokenEnum::QQ_API_TOKEN_FUND_COST);
        if (! $token) {
            // 发送提醒
            $res = TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            if (! $res) {
                echo self::getError(0) . date('Y-m-d H:i:s') . PHP_EOL;
            }
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }
        $startDate = $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date'))));
        $endDate = $this->params['end_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date'))));
        $this->params = [
            'access_token' => $token,
            'account_id' => $model->getAttr('advertiser_id'),
            'date_range' => ['start_date' => $startDate, 'end_date' => $endDate],
            'fields' => QqEnum::ACCOUNT_REPORT_FIELD,
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => QqEnum::MAX_PAGE_SIZE,
        ];
        $this->response = FinanceService::getAdvertiserDailyFlow($this->params);
        if (! $this->response) {
            return self::setError('请求有误');
        }
        $this->thisResponseData = filterData($this->response['data'], 'list');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }

    /**
     * 获取素材报表.
     * @param CostTaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMaterialDailyReport(CostTaskAccountModel $model): bool
    {
        // 33971333_QQ_TOKEN
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'), TokenEnum::QQ_API_TOKEN_DAILY_COST);
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }
        $startDate = $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date'))));
        $endDate = $this->params['end_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date'))));
        $this->params = [
            'access_token' => $token,
            'account_id' => $model->getAttr('advertiser_id'),
            'date_range' => ['start_date' => $startDate, 'end_date' => $endDate],
            'level' => QqEnum::REPORT_LEVEL_MATERIAL_VIDEO,
            'group_by' => ['date', 'material_id'],
            'fields' => QqEnum::MATERIAL_REPORT_FIELD,
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => QqEnum::MAX_PAGE_SIZE,
        ];

        $this->response = FinanceService::_getServiceMaterialDailyReport($this->params);
        $this->thisResponseData = filterData($this->response['data'], 'list');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }

    /**
     * 获取素材报表.
     * @param CostTaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getMaterialPicDailyReport(CostTaskAccountModel $model): bool
    {
        // 33440444_QQ_TOKEN
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'), TokenEnum::QQ_API_TOKEN_DAILY_COST);
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }
        $startDate = $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date'))));
        $endDate = $this->params['end_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date'))));
        $this->params = [
            'access_token' => $token,
            'account_id' => $model->getAttr('advertiser_id'),
            'date_range' => ['start_date' => $startDate, 'end_date' => $endDate],
            'level' => QqEnum::REPORT_LEVEL_MATERIAL_PIC,
            'group_by' => ['date', 'material_id'],
            'fields' => QqEnum::MATERIAL_REPORT_FIELD,
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => QqEnum::MAX_PAGE_SIZE,
        ];
        $this->response = FinanceService::_getServiceMaterialDailyReport($this->params);
        $this->thisResponseData = filterData($this->response['data'], 'list');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }

    public function getVideoList(CostTaskAccountModel $model, string $materialId = ''): bool
    {
        // 32260910_QQ_TOKEN
        $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'), TokenEnum::QQ_API_TOKEN_DAILY_COST);
        if (! $token) {
            // 发送提醒
            TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }

        $this->params = [
            'access_token' => $token,
            'account_id' => $model->getAttr('advertiser_id'),
            'page' => 1,
            'page_size' => 500,
            'filtering' => json_encode([
                [
                    'field' => 'media_id',
                    'operator' => 'EQUALS',
                    'values' => [$materialId],
                ],
            ]),
            'fields' => ['created_time'],
        ];

        $this->response = MaterialService::getVideoList($this->params);
        $this->thisResponseData = filterData($this->response['data'], 'list');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }

    /**
     * 获取报表.
     * @param CostTaskAccountModel $model 任务模型
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAccountReportList(CostTaskAccountModel $model): bool
    {
        // 33610059_QQ_TOKEN
         $token = AccountService::getToken($this->getMediaId(), $model->getAttr('advertiser_id'), TokenEnum::QQ_API_TOKEN_FUND_COST);
        if (! $token) {
            // 发送提醒
            $res = TaskNoticeService::systemErrorNotice(ServiceCostEnum::ERROR_TOKEN_CODE, $model->getAttr('account_id'), 'token获取失败，账户授权可能失效，请及时处理', $model->getKey());
            if (! $res) {
                echo self::getError(0) . date('Y-m-d H:i:s') . PHP_EOL;
            }
            return self::setError('token获取失败，账户授权可能失效，请及时处理');
        }
        $startDate = $this->params['start_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date'))));
        $endDate = $this->params['end_date'] ?? date('Y-m-d', strtotime(strval($model->getAttr('stat_date'))));
        $this->params = [
            'access_token' => $token,
            'account_id' => $model->getAttr('advertiser_id'),
            'date_range' => [
                'start_date' => $startDate,
                'end_date' => $endDate,
            ],
            'level' => QqEnum::REPORT_LEVEL_ADVERTISER,
            'fields' => QqEnum::MATERIAL_REPORT_FIELD,
            'page' => ($this->params['page'] ?? 0) + 1,
            'page_size' => QqEnum::ADVERTISER_MAX_PAGE_SIZE,
        ];

        $this->response = FinanceService::getAdvertiserReport($this->params);
        if (! $this->response) {
            return self::setError('请求有误');
        }
        $this->thisResponseData = filterData($this->response['data'], 'list');
        $this->responseData = array_merge($this->responseData, $this->thisResponseData);
        return true;
    }
}
